package uk.ac.cam.echo.reader;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Set;

import uk.ac.cam.echo.messages.CheckInMessage;
import uk.ac.cam.echo.messages.UserMessage;
import uk.ac.cam.echo.messages.UserTableMessage;

/**
 * @author Andrius Dagys
 */

public class Client {

	private ObjectInputStream ois;
	private ObjectOutputStream ous;

	/**
	 * Handles the connection to the server
	 * 
	 * @param server
	 * @param port
	 * @throws IOException
	 */

	public Client(String server, int port) {
		try {
			final Socket s = new Socket(server, port);
			InputStream is = s.getInputStream();
			OutputStream os = s.getOutputStream();

			ois = new ObjectInputStream(is);
			ous = new ObjectOutputStream(os);

			System.out.println("Successfully connected to the server at " + server + " " + port);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * Get user data from the server to store in the cache
	 * @return
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public HashMap<String, UserMessage> getUserTable() throws IOException,
			ClassNotFoundException {
		
		HashMap<String, UserMessage> users = null;

		UserTableMessage utmRequest = new UserTableMessage(null);
		
		ous.writeObject(utmRequest);		
		UserTableMessage utmResponse = (UserTableMessage) ois.readObject();
		
		users = new HashMap<String, UserMessage>();
		for (UserMessage ums : utmResponse.getList()) {
			users.put(ums.getRFID(), ums);
		}	
		return users;
	}
	
	/**
	 * Submit the checkin to the server.
	 * @param tags
	 * tags of users currently being swiped
	 * 
	 * @param attractionId
	 * the id of the attraction
	 */
	public void checkInUser(Set<String> tags, int attractionId, String attractionLoc) {
		for (String tag : tags) {
			CheckInMessage cmsg = new CheckInMessage(tag, attractionId, attractionLoc, System.currentTimeMillis());
			try {
				ous.writeObject(cmsg);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Get user details from the server as a UserMessage NOTE: Currently
	 * supports only one tag, i.e. selects the first tag from the set.
	 * 
	 * @param tags
	 *            A set containing the scanned tag ids
	 * @throws IOException
	 * @throws ClassNotFoundException
	 * @throws UserNotFoundException
	 */
	public String getUserInfo(Set<String> tags) throws UserNotFoundException,
			IOException, ClassNotFoundException {
		String tag = tags.iterator().next();

		UserMessage request = new UserMessage(tag);
		UserMessage userDetails = null;

		ous.writeObject(request);
		Object reply = ois.readObject();
		userDetails = (UserMessage) reply;

		if (userDetails.getSurname() == null)
			throw new UserNotFoundException();
		return userDetails.getForename() + " " + userDetails.getSurname();
	}
}